package com.ygy.component;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ygy.GoodsApplication;
import com.ygy.entity.Messages;
import com.ygy.entity.Users;
import com.ygy.service.impl.MessagesServiceImpl;
import com.ygy.service.impl.UsersServiceImpl;
import org.apache.catalina.core.ApplicationContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author websocket服务
 */
@ServerEndpoint(value = "/imserver/{username}")
@Component
public class WebSocketServer implements InitializingBean {
    private static final Logger log = LoggerFactory.getLogger(WebSocketServer.class);
    /**
     * 记录当前在线连接数
     * // 有一个sessionMap来存储WebSocketSessio
     */
    public static final Map<String, Session> sessionMap = new ConcurrentHashMap<>();
    /**
     * 连接建立成功调用的方法
     */
    /**
     * @className: WebSocketServer
     * @author: Ye
     * @描述: 注入聊天接口
     * @date: 2024/4/7 12:39
     * @version: 1.0
     */


    private static MessagesServiceImpl messagesService;

    private static UsersServiceImpl usersService;

         @Autowired
        public WebSocketServer(MessagesServiceImpl messagesService, UsersServiceImpl usersService ){
            WebSocketServer.messagesService = messagesService;
            WebSocketServer.usersService = usersService;
        }

        public WebSocketServer(){

        }


    @OnOpen
    public void onOpen(Session session, @PathParam("username") String username) {

        sessionMap.put(username, session);

        List<Messages> unreadMessages = messagesService.getUnreadMessagesByReceiver(username);
       log.info("有新用户加入，username={}, 当前在线人数为：{}", username, sessionMap.size());
        if (!unreadMessages.isEmpty()) {
            for (Messages message : unreadMessages) {
                 Users users = usersService.getById(message.getSenderId());//拿到用户头像

                JSONObject jsonObject = new JSONObject();
                jsonObject.set("type", "text_message"); // 添加消息类型
                jsonObject.set("from", message.getFormUsername());
                jsonObject.set("avatar", users.getAvatar());
                jsonObject.set("receiverId",message.getReceiverId());
                jsonObject.set("senderId",message.getSenderId());
                jsonObject.set("to", message.getToUsername());
                jsonObject.set("text", message.getContent());
                this.sendMessage(jsonObject.toString(), session);
                log.info("发送未读消息给用户username={}，消息：{}", username, jsonObject.toString());

                // 标记消息为已读（可选，取决于业务逻辑是否需要立即标记为已读）
                message.setIsRead(1);
               // messagesService.update(message);
                messagesService.saveOrUpdate(message);
            }
        }
//        JSONObject result = new JSONObject();
//        JSONArray array = new JSONArray();
//        result.set("users", array);
//        for (Object key : sessionMap.keySet()) {
//            JSONObject jsonObject = new JSONObject();
//            jsonObject.set("username", key);
//            // {"username", "zhang", "username": "admin"}
//            array.add(jsonObject);
//        }
////        {"users": [{"username": "zhang"},{ "username": "admin"}]}
//        sendAllMessage(JSONUtil.toJsonStr(result));  // 后台发送消息给所有的客户端

    }
    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(Session session, @PathParam("username") String username) {
        sessionMap.remove(username);
        log.info("有一连接关闭，移除username={}的用户session, 当前在线人数为：{}", username, sessionMap.size());
    }
    /**
     * 收到客户端消息后调用的方法
     * 后台收到客户端发送过来的消息
     * onMessage 是一个消息的中转站
     * 接受 浏览器端 socket.send 发送过来的 json数据
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, Session session, @PathParam("username") String username) {
        log.info("服务端收到用户username={}的消息:{}",username, message);


        // 解析消息并处理不同类型的消息
        try {
            JSONObject obj = JSONUtil.parseObj(message);
            String type = obj.getStr("type");
            switch (type) {
//                case "user_info": // 如果是头像更新消息
//                    String avatar = obj.getStr("avatar");
//                    handleAvatarUpdate(avatar, username, session);
//                    break;
                case "text_message":

                    String toUsername = obj.getStr("to"); // to表示发送给哪个用户，比如 admin
                    String avatar = obj.getStr("avatar");
                    Integer receiverId = obj.getInt("receiverId");
                    Integer senderId = obj.getInt("senderId");
                    String text = obj.getStr("text"); // 发送的消息文本  hello
                    // {"to": "admin", "text": "聊天文本"}
                    Session toSession = sessionMap.get(toUsername); // 根据 to用户名来获取 session，再通过session发送消息文本
                    log.info("toSession是什么", toSession);
                    System.out.println(toSession);
                    /**
                     *把解析的数据存入到聊天表
                     * 1.创建Messages对象
                     * 2.保存到数据库

                     */
                    //1.创建Messages对象
                    Messages messages = new Messages();
                    messages.setReceiverId(receiverId);
                    messages.setSenderId(senderId);
                    messages.setFormUsername(username);
                    messages.setToUsername(toUsername);
                    messages.setContent(text);
                    messages.setIsRead(0);
                    messages.setCreatedAt(LocalDateTime.now());
                    //2.保存到数据库
                    messagesService.save(messages);

                    if (toSession != null) {
                        // 服务器端 再把消息组装一下，组装后的消息包含发送人和发送的文本内容
                        // {"from": "zhang", "text": "hello"}
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.set("type", "text_message"); // 添加消息类型
                        jsonObject.set("from", username);  // from 是 zhang
                        jsonObject.set("to", toUsername);
                        jsonObject.set("receiverId", receiverId);
                        jsonObject.set("senderId", senderId);
                        jsonObject.set("avatar", avatar);
                        jsonObject.set("text", text);  // text 同上面的text
                        this.sendMessage(jsonObject.toString(), toSession);

                        messages.setIsRead(1);
                        messagesService.saveOrUpdate(messages);
                        log.info("发送给用户username={}，消息：{}", toUsername, jsonObject.toString());
                    } else {
                        log.info("发送失败，未找到用户username={}的session", toUsername);
                    }
                    break;
                default:
                    log.warn("Unknown message type: {}", type);
            }
        } catch (Exception e) {
            log.error("Error parsing message for user {}: {}", username, e.getMessage());
        }
   // }
//        =================================================================

//        JSONObject obj = JSONUtil.parseObj(message);
//        String toUsername = obj.getStr("to"); // to表示发送给哪个用户，比如 admin
//        String text = obj.getStr("text"); // 发送的消息文本  hello
//        // {"to": "admin", "text": "聊天文本"}
//        Session toSession = sessionMap.get(toUsername); // 根据 to用户名来获取 session，再通过session发送消息文本
//        /**
//         *把解析的数据存入到聊天表
//         * 1.创建Messages对象
//         * 2.保存到数据库
//
//         */
//        //1.创建Messages对象
//        Messages messages = new Messages();
//        messages.setFormUsername(username);
//        messages.setToUsername(toUsername);
//        messages.setContent(text);
//        messages.setIsRead(0);
//        messages.setCreatedAt(LocalDateTime.now());
//        //2.保存到数据库
//        messagesService.save(messages);
//
//        if (toSession != null) {
//            // 服务器端 再把消息组装一下，组装后的消息包含发送人和发送的文本内容
//            // {"from": "zhang", "text": "hello"}
//            JSONObject jsonObject = new JSONObject();
//            jsonObject.set("from", username);  // from 是 zhang
//            jsonObject.set("text", text);  // text 同上面的text
//            this.sendMessage(jsonObject.toString(), toSession);
//
//            messages.setIsRead(1);
//            messagesService.saveOrUpdate(messages);
//            log.info("发送给用户username={}，消息：{}", toUsername, jsonObject.toString());
//        } else {
//            log.info("发送失败，未找到用户username={}的session", toUsername);
//        }

    }
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("发生错误");
        error.printStackTrace();
    }
    /**
     * 服务端发送消息给客户端
     */
    private void sendMessage(String message, Session toSession) {
        try {
            log.info("服务端给客户端[{}]发送消息{}", toSession.getId(), message);
            toSession.getBasicRemote().sendText(message);
        } catch (Exception e) {
            log.error("服务端发送消息给客户端失败", e);
        }
    }
    /**
     * 服务端发送消息给所有客户端
     */
    private void sendAllMessage(String message) {
        try {
            for (Session session : sessionMap.values()) {
                log.info("服务端给客户端[{}]发送消息{}", session.getId(), message);
                session.getBasicRemote().sendText(message);
            }
        } catch (Exception e) {
            log.error("服务端发送消息给客户端失败", e);
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {

    }


    // 新增方法：处理用户头像更新
    private void handleAvatarUpdate(String avatar, String username, Session session) {
        // 存储或更新用户头像信息（这里简单起见，只打印日志）
        log.info("Received avatar update for user {}: {}", username, avatar);

        // 可以选择广播头像更新给所有在线用户或特定用户
        // 例如，广播给所有在线用户：
        sessionMap.forEach((key, value) -> {
            if (value != session) { // 不发送给发送者本身
                JSONObject jsonObject = new JSONObject();
                jsonObject.set("type", "user_info");
                jsonObject.set("username", username);
                jsonObject.set("avatar", avatar);
                this.sendMessage(jsonObject.toString(), value);
            }
        });
    }
}

